package com.lb.comb;

import com.google.common.collect.Lists;

import java.util.ArrayList;
import java.util.List;

public class CombinationUtil {

    public static <T> List<List<T>> combination(List<T> datas, int number) {
        if ((datas == null) || (datas.size() == 0) || (datas.size() < number)) {
            return null;
        }
        List<List<T>> combines = new ArrayList<>();
        List<T> temps = new ArrayList<T>();

        combine(datas, 0, number, temps, combines);
        return combines;
    }

    public static <T> void combine(List<T> datas, int begin, int number, List<T> temps, List<List<T>> combines) {
        if (number == 0) {
            List<T> aCombine = new ArrayList<T>();
            aCombine.addAll(temps);
            combines.add(aCombine);
            return;
        }
        if (begin == datas.size()) {
            return;
        }
        temps.add(datas.get(begin));
        combine(datas, begin + 1, number - 1, temps, combines);
        temps.remove(datas.get(begin));
        combine(datas, begin + 1, number, temps, combines);
    }

    public static void main(String args[]) {
        /*Character chs[] = { 'a', 'b', 'c', 'd', 'e'};
        List<List<Character>> combines = combination(chs, 3);
        for (List<Character> data : combines) {
            System.out.println(data.toString());
        }*/
        List<String> nums = new ArrayList<String>();
        nums.add("A");
        nums.add("B");
//        nums.add("C");
//        nums.add("D");
//        nums.add("E");
//        List<List<String>> combines = combination(nums, 5);
//        for (List<String> combine : combines) {
//            System.out.println(combine);
//        }
        List<Integer> subSegment = new ArrayList(){{
            add(2);
//            add(3);
//            add(4);
//            add(5);
        }};
        getAllCombs(nums, 2, subSegment).forEach(System.out::println);
    }

    public static List<List<String>> getAllCombs(List<String> list, int segment, List<Integer> subSegments) {
        List<List<String>> combines = combination(list, segment);
        List<List<String>> finalCombines = Lists.newArrayList();

        subSegments.forEach(item -> {
            combines.forEach(combine -> {
                List<List<String>> temp = combination(combine, item);
                temp.forEach(comb -> {
                    finalCombines.add(comb);
                });
            });
        });
        return finalCombines;
    }
}